using Bee.Base.Abstractions;
using Bee.Base.Abstractions.Tasks;
using Bee.Base.Models.Tasks;

using FFMpegCore;

using Ke.Bee.Localization.Localizer.Abstractions;

using LanguageExt;

namespace Bee.Plugin.Multimedia.Tasks;

public class VideoSplitTaskHandler(ICoverHandler coverHandler, ILocalizer localizer) :
    TaskHandlerBase<VideoSplitArguments>(coverHandler)
{
    private readonly ILocalizer _l = localizer;

    public override async Task<Fin<Unit>> ExecuteAsync(TaskItem taskItem,
        VideoSplitArguments arguments,
        Action<double> progressCallback,
        CancellationToken cancellationToken = default)
    {
        var fileName = Path.GetFileNameWithoutExtension(taskItem.Input);

        var times = taskItem.CustomArguments?.Split(MultimediaProcessConsts.DefaultDelimiter).Distinct();
        if (times == null)
        {
            return Fin<Unit>.Fail(string.Format(_l["Task.TaskItem.Arguments.Empty"], fileName));
        }

        // 分析原视频信息
        //var analysis = FFProbe.Analyse(taskItem.Input);
        //var video = analysis.VideoStreams.FirstOrDefault();
        var timeList = ParseTimeList(times);
        int processedCount = 0; // 已处理时间戳数量

        // 00:00:01-00:00:05|00:00:15-00:00:25|00:00:55-00:00:59
        foreach (var time in timeList)
        {
            var ext = Path.GetExtension(taskItem.Input);

            // 输出文件
            var outputFile = Path.Combine(arguments.OutputDirectory,
                $"{fileName}.{time.Start.TotalSeconds}{ext}")
                ;

            await FFMpeg.SubVideoAsync(taskItem.Input, outputFile, time.Start, time.End);

            processedCount++;
            progressCallback((int)(processedCount / (double)timeList.Count * 100));
        }

        return Fin<Unit>.Succ(Unit.Default);
    }

    private List<TimeTuple> ParseTimeList(IEnumerable<string> times)
    {
        List<TimeTuple> list = [];
        foreach (var time in times)
        {
            if (!time.Contains('-'))
            {
                continue;
            }

            var arr = time.Split('-');
            if (TimeSpan.TryParse(arr[0], out TimeSpan start) && TimeSpan.TryParse(arr[1], out TimeSpan end) && end > start)
            {
                list.Add(new TimeTuple(start, end));
            }
        }
        return list;
    }

    internal class TimeTuple(TimeSpan start, TimeSpan end)
    {
        public TimeSpan Start { get; set; } = start;
        public TimeSpan End { get; set; } = end;
    }
}